<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<section>
    <h4>闭包的形式</h4>
    <ul>
        <li>函数内部返回函数，供外部调用</li>
    </ul>
</section>
<section>
    <h4>闭包特性</h4>
    <ul>
        <li>闭包函数可以访问上一层的变量</li>
        <li>闭包函数访问的变量会一直保持在内存当中</li>
    </ul>
</section>
<div>
    <span>防抖测试</span>
    <button id="debounceBtn">click</button>
</div>
<div>
    <span>节流测试</span>
    <button id="throttleBtn">click</button>
</div>

<script>
    // 闭包的应用
    function handleClick(...args) {
        console.log('click', ...args);
    }

    // 第一次不是立即执行
    function debounce1(fn, delay = 300) {
        let timer = null;

        return function (...args) {
            clearTimeout(timer);
            timer = setTimeout(function () {
                fn && fn.call(null, ...args);
            }, delay)
        }
    }

    // 第一次立即执行
    function debounce2(fn, delay = 300) {
        let timer = null;
        let timer2 = null;

        return function (...args) {
            if (!timer) {
                fn && fn.call(null, ...args);
                timer = true;
                timer2 = setTimeout(function () {
                    timer = null;
                }, delay);
            } else {
                clearTimeout(timer2);
                clearTimeout(timer);
                timer = setTimeout(function () {
                    fn && fn.call(null, ...args);
                    timer = null;
                }, delay);
            }
        }
    }


    // 第一次不是立即执行
    function throttled1(fn, delay = 300) {
        let timer = null;

        return function (...args) {
            if (!timer) {
                timer = setTimeout(function () {
                    fn && fn.call(null, ...args);
                    timer = null;
                }, delay);
            }
        }
    }

    // 第一次立即执行
    function throttled2(fn, delay = 500) {
        let oldTime = Date.now();
        return function (...args) {
            let newTime = Date.now();
            if (newTime - oldTime > delay) {
                fn && fn.call(null, ...args);
                oldTime = Date.now();
            }
        }
    }

    debounceBtn.onclick = debounce2(handleClick, 1000);
    throttleBtn.onclick = throttled2(handleClick, 1000);
</script>
</body>
</html>
